package com.itheima.app.manager.umsManager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.app.exception.BusinessException;
import com.itheima.app.interceptor.AdminHolder;
import com.itheima.commons.JwtUtil;
import com.itheima.commons.R;
import com.itheima.domain.db.ums.*;
import com.itheima.service.umsService.*;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.UmsAdminInfoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author DogeGuo
 */
@Component
public class UmsAdminManager {
    @DubboReference
    UmsAdminService umsAdminService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 用户登录
     *
     * @param username
     * @param password
     * @return
     */
    public R login(String username, String password) {
        //1.根据用户名查找用户
        UmsAdmin umsAdmin = umsAdminService.selectByUsername(username);

        //2.判断用户是否存在
        if (umsAdmin == null) {
            //不存在
            throw new BusinessException("用户名不存在");
        }

        //3.判断密码是否一致
        if (!StrUtil.equals(SecureUtil.md5(password), umsAdmin.getPassword())) {
            //不一致
            throw new BusinessException("密码不正确");
        }

        //4.判断用户是否启用
        if (umsAdmin.getStatus() == 0) {
            throw new BusinessException("改用户已禁用");
        }


        /*//5.准备用户数据(用户名,密码),生成token
        Map<String, String> userMap = new HashMap<>();
        userMap.put("username", umsAdmin.getUsername());
        userMap.put("password", umsAdmin.getPassword());
        String token = JwtUtil.createToken(userMap);

        //6.为了避免每次都解析token,将token作为key,用户的json数据做为value,放入redis中
        stringRedisTemplate.opsForValue().set(ConstantUtil.ADMIN_TOKEN + token, JSON.toJSONString(umsAdmin), Duration.ofDays(30));

        return R.ok(token);*/
        //将账号密码置空,通过hutool转为map对象
        umsAdmin.setPassword(null);
        Map<String, Object> objectMap = BeanUtil.beanToMap(umsAdmin);
        //生成token
        String token = JwtUtil.createToken(objectMap);

        //把token保存到redis中,admin数据保存value中,时效5天
        stringRedisTemplate.opsForValue().set(ConstantUtil.ADMIN_TOKEN + token, JSON.toJSONString(umsAdmin), Duration.ofDays(5));

        //将返回的数据转为map,返回给前端
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("tokenHead", "Bearer ");
        resultMap.put("token", token);

        return R.ok(resultMap);
    }

    @DubboReference
    UmsAdminRoleRelationService umsAdminRoleRelationService;

    @DubboReference
    UmsRoleService umsRoleService;

    @DubboReference
    UmsRoleMenuRelationService umsRoleMenuRelationService;

    @DubboReference
    UmsMenuService umsMenuService;

    /**
     * 获取当前登录者用户信息
     *
     * @return
     */
    public R getInfo() {
        //获取当前登录的id
        Long adminId = AdminHolder.get().getId();
        //根据当前用户id,获取用户信息
        UmsAdmin admin = umsAdminService.selectById(adminId);

        //查询角色关系表对应的角色id
        List<UmsAdminRoleRelation> roles = umsAdminRoleRelationService.getRoles(adminId);

        //查询角色表,查询当前用户的角色集合
        List<Long> roleIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(roles)) {
            roles.forEach(roleRelation -> {
                roleIds.add(roleRelation.getRoleId());
            });
        }

        //查询角色表,获取角色对应的名称集合
        List<UmsRole> roleList = umsRoleService.findByRoleIds(roleIds);

        //获取角色的名称集合
        List<String> roleNames = roleList.stream().map(role -> {
            return role.getName();
        }).collect(Collectors.toList());

        //查询角色菜单表,查询菜单集合
        //根据角色id集合,查询对应菜单id集合
        List<UmsRoleMenuRelation> roleMenuRelations = umsRoleMenuRelationService.findByRoleIds(roleIds);

        //获取菜单id集合
        List<Long> menuIds = roleMenuRelations.stream().map(roleMenuRelation -> {
            return roleMenuRelation.getMenuId();
        }).collect(Collectors.toList());

        //根据菜单id集合查询,菜单集合对象
        List<UmsMenu> umsMenus = umsMenuService.findByMenuIds(menuIds);

        //封装返回数据
        UmsAdminInfoVo vo = new UmsAdminInfoVo();
        vo.setRoles(roleNames);
        vo.setIcon(admin.getIcon());
        vo.setMenus(umsMenus);
        vo.setUsername(admin.getUsername());
        return R.ok(vo);
    }

    /*
     * 分页查询用户信息
     * */
    public R findByPage(Integer pageNum, Integer pageSize, String keyword) {

        //2.远程调用service,返回pageBeanVo
        PageBeanVo pageBeanVo = umsAdminService.findAll(pageNum, pageSize, keyword);

        //6.返回pageBeanVo
        return R.ok(pageBeanVo);

    }

    /*
     * 用户注册
     * */
    public R saveUmsAdmin(UmsAdmin umsAdmin) {

        UmsAdmin findByUserName = umsAdminService.selectByUsername(umsAdmin.getUsername());
        if (findByUserName != null) {
            return R.err("账号已存在");
        }
        // 对密码进行加密存储
        umsAdmin.setPassword(SecureUtil.md5(umsAdmin.getPassword()));


        long time = System.currentTimeMillis();
        Date date = new Date(time);
        umsAdmin.setCreateTime(date);

        UmsAdmin umsAdmin1 = umsAdminService.saveUmsAdmin(umsAdmin);


        return R.ok(umsAdmin1);

    }

    /*
     * 删除用户
     * */
    public R removeUmsAdmin(Integer id) {

        umsAdminService.removeUsmAdmin(id);

        return R.ok("删除成功");
    }

    /*
     * 登出
     * */
    public R logoutUmsAdmin() {
        //获取当前登录的id
        Long adminId = AdminHolder.get().getId();
        //根据当前用户id,获取用户信息
        UmsAdmin umsAdmin = umsAdminService.selectById(adminId);
        long time = System.currentTimeMillis();
        Date date = new Date(time);

        umsAdmin.setLoginTime(date);
        umsAdminService.updateTime(umsAdmin);
        umsAdmin.setPassword(null);
        Map<String, Object> objectMap = BeanUtil.beanToMap(umsAdmin);
        //生成token
        String token = JwtUtil.createToken(objectMap);

        stringRedisTemplate.delete(ConstantUtil.ADMIN_TOKEN + token);

        return R.ok("登出成功");
    }

    /*
     * 刷新token
     * */
    public void refreshToken() {
        UmsAdmin umsAdmin = AdminHolder.get();
        String username = umsAdmin.getUsername();
        UmsAdmin admin = umsAdminService.selectByUsername(username);

        // 刷新token
        admin.setPassword(null);
        BeanUtil.beanToMap(admin);
        String token = JwtUtil.createToken(BeanUtil.beanToMap(admin));

        stringRedisTemplate.opsForValue().set(ConstantUtil.ADMIN_TOKEN + token, JSON.toJSONString(admin), Duration.ofHours(1));
    }

    //获取指定用户的角色
    public R findRoleById(Integer id) {

        List<UmsAdminRoleRelation> UmsAdminRoleRelations = umsAdminRoleRelationService.getRoles(Long.valueOf(id));

        /*List<Long> list = new ArrayList<>();
        for (UmsAdminRoleRelation role : UmsAdminRoleRelation) {
            list.add(role.getRoleId());

        }*/

        if (CollUtil.isNotEmpty(UmsAdminRoleRelations)) {
            List<Long> roleIds = UmsAdminRoleRelations.stream().map(UmsAdminRoleRelation::getRoleId).collect(Collectors.toList());
            List<UmsRole> roles = umsRoleService.findByRoleIds(roleIds);
            return R.ok(roles);
        }
        return null;
    }

    /*
     * 给用户分配角色
     * */
    public R updateRoleById(Long adminId, List<Long> roleIds) {
        umsAdminService.updateRoleById(adminId, roleIds);
        return R.ok("修改成功");
    }

    /*
     * 修改用户信息
     * */
    public R updateUsmAdmin(Long id, UmsAdmin umsAdmin) {
        //获取旧用户信息
        UmsAdmin umsAdminOld = umsAdminService.selectById(id);

        //判断用户名是否存在
        if (umsAdminService.selectByUsername(umsAdmin.getUsername()) != null && !umsAdminOld.getUsername().equals(umsAdmin.getUsername())) {
            return R.err("用户名已经存在");
        };
        //
        String oldPassword = umsAdminOld.getPassword();
        String newPassword = umsAdmin.getPassword();
        if (!StrUtil.equals(newPassword, oldPassword)) {
            // 密码一致的话 说明这次修改没有修改密码
            // 取反 修改密码
            umsAdmin.setPassword(SecureUtil.md5(newPassword));
        }
        umsAdminService.updateUsmAdmin(umsAdmin);
        return R.ok("");

    }

    //修改状态信息
    public R updateStatues(Long id, Integer status) {
        //根据id获取用户信息
        UmsAdmin umsAdmin = umsAdminService.selectById(id);

        //设置状态
        umsAdmin.setStatus(status);

        //修改
        umsAdminService.updateUsmAdmin(umsAdmin);

        return R.ok("");
    }

    //修改账号密码
    public R updatePassword(String username, String newPassword, String oldPassword) {
        //根据id获取用户信息
        UmsAdmin umsAdmin = umsAdminService.selectByUsername(username);

        //对比新密码和旧密码
        if(!SecureUtil.md5(oldPassword).equals(umsAdmin.getPassword())){
            return R.err("密码错误");
        }
        umsAdmin.setPassword(SecureUtil.md5(newPassword));
        umsAdminService.updateUsmAdmin(umsAdmin);
        return R.ok("");
    }

    //获取指定用户信息
    public R getById(Long id) {
        UmsAdmin umsAdmin = umsAdminService.selectById(id);

        return R.ok(umsAdmin);
    }
}
